;http://www.autoitscript.com/forum/topic/11888-yet-another-copy-with-progress/#
;7/31/2011
;post #16 by "zedna"

Func _CopyWithProgress($sFrom, $sTo, $sTitle = '')
	
	Const $FO_MOVE                   = 0x0001
	Const $FO_COPY                   = 0x0002
	Const $FO_DELETE                 = 0x0003
	Const $FO_RENAME                 = 0x0004

	Const $FOF_MULTIDESTFILES        = 0x0001
	Const $FOF_CONFIRMMOUSE          = 0x0002
	Const $FOF_SILENT                = 0x0004
	Const $FOF_RENAMEONCOLLISION     = 0x0008
	Const $FOF_NOCONFIRMATION        = 0x0010
	Const $FOF_WANTMAPPINGHANDLE     = 0x0020
	Const $FOF_ALLOWUNDO             = 0x0040
	Const $FOF_FILESONLY             = 0x0080
	Const $FOF_SIMPLEPROGRESS        = 0x0100
	Const $FOF_NOCONFIRMMKDIR        = 0x0200
	Const $FOF_NOERRORUI             = 0x0400
	Const $FOF_NOCOPYSECURITYATTRIBS = 0x0800
	Const $FOF_NORECURSION           = 0x1000
	Const $FOF_NO_CONNECTED_ELEMENTS = 0x2000
	Const $FOF_WANTNUKEWARNING       = 0x4000
	Const $FOF_NORECURSEREPARSE      = 0x8000
	
    Local $SHFILEOPSTRUCT, $pFrom, $pTo, $pTitle, $aDllRet, $nError = 0
    Local $flags = BitOR($FOF_NOCONFIRMMKDIR, $FOF_NOCONFIRMATION, $FOF_NOERRORUI)
    Local    $SHFILEOPSTRUCT = DllStructCreate("hwnd hwnd;uint wFunc;ptr pFrom;ptr pTo;int fFlags;int fAnyOperationsAborted;ptr hNameMappings;ptr lpszProgressTitle")
    DllStructSetData($SHFILEOPSTRUCT, "hwnd", 0)
    DllStructSetData($SHFILEOPSTRUCT, "wFunc", $FO_COPY)
		$pFrom = DllStructCreate("char[" & StringLen($sFrom)+2 & "]")
    DllStructSetData($pFrom, 1, $sFrom)
    DllStructSetData($pFrom, 1, Chr(0), StringLen($sFrom)+2) ; second null at the end
    DllStructSetData($SHFILEOPSTRUCT, "pFrom", DllStructGetPtr($pFrom))
		$pTo = DllStructCreate("char[" & StringLen($sTo)+2 & "]")
    DllStructSetData($pTo, 1, $sTo)
    DllStructSetData($pTo, 1, Chr(0), StringLen($sTo)+2) ; second null at the end
    DllStructSetData($SHFILEOPSTRUCT, "pTo", DllStructGetPtr($pTo))
        DllStructSetData($SHFILEOPSTRUCT, "fAnyOperationsAborted", 0)
    DllStructSetData($SHFILEOPSTRUCT, "hNameMappings", 0)
	If $sTitle <> '' Then
		$pTitle = DllStructCreate("char[" & StringLen($sTitle)+1 & "]")
        ;$pTitle = DllStructCreate("char[4]")
		DllStructSetData($pTitle, 1, $sTitle)
        ;DllStructSetData($pTitle, 1, 'aaa')
		DllStructSetData($pTitle, 1, Chr(0), StringLen($sTitle)+1) ; null at the end

        $flags = BitOR($flags, $FOF_SIMPLEPROGRESS)
        DllStructSetData($SHFILEOPSTRUCT, "lpszProgressTitle", DllStructGetPtr($pTitle))
;~      DllStructSetData($SHFILEOPSTRUCT, "lpszProgressTitle", 'aaa')
    Else
        DllStructSetData($SHFILEOPSTRUCT, "lpszProgressTitle", 0)
    EndIf
	DllStructSetData($SHFILEOPSTRUCT, "fFlags", $flags)
    $aDllRet = DllCall("shell32.dll", "int", "SHFileOperation", "ptr", DllStructGetPtr($SHFILEOPSTRUCT))
    If @error Or $aDllRet[0] <> 0 Then
        $aDllRet = DllCall("kernel32.dll", "long", "GetLastError")
        If Not @error Then $nError = $aDllRet[0]
    EndIf
        ; test if button Abort was pressed
    If DllStructGetData($SHFILEOPSTRUCT, "fAnyOperationsAborted") Then $nError = -1

    $pFrom = 0
    $pTo = 0
    $pTitle = 0
    $SHFILEOPSTRUCT = 0
	If $nError <> 0 Then
        SetError($nError)
        Return False
    EndIf
    Return True
EndFunc